using System;
using LS.Digitize;

namespace LS.Saving
{
    public struct DataObject
    {
        public Type type;
        public object value;
    }

    public class DataObjectSerializer : CompoundSerializer<DataObject>
    {
        public DataObjectSerializer() : base(typeof(DataObject), typeof(Type))
        {
            
        }


        public override void WriteData(IWriter writer, DataObject obj)
        {
            ISerializer<Type> typeSerializer = SubSerializer as  ISerializer<Type>;
            ISerializer objectSerializer = SerializerUtil.GetOrCreateSerializer(obj.value.GetType());
            using (writer.WriteObjectScope())
            {
                using (writer.WritePropertyScope(TypeFieldName))
                {
                    typeSerializer.WriteData(writer, obj.type);
                }

                using (writer.WritePropertyScope(ValueFieldName))
                {
                    if(obj.value == null)
                        writer.WriteNull();
                    else
                        objectSerializer.Write(writer, obj.value);
                }
            }
        }

        public override DataObject ReadData(IReader reader)
        {
            ISerializer<Type> typeSerializer = SubSerializer as  ISerializer<Type>;
            Type type = null;
            object value = null;
            using (reader.ReadObjectScope())
            {
                string propertyName = reader.ReadPropertyName();
                type = typeSerializer.ReadData(reader);

                propertyName = reader.ReadPropertyName();
                if (type == null)
                    reader.SkipElement();
                else
                    value = SerializerUtil.GetOrCreateSerializer(type).Read(reader);
            }

            return new DataObject()
            {
                type = type,
                value = value
            };
        }

        public override void ReadInto(IReader reader, ref DataObject obj)
        {
            throw new NotImplementedException();
        }
    }
}